package reflect;

import java.lang.reflect.Method;
import java.util.Scanner;

/**
 * java反射机制
 * 反射是java的动态机制.可以在程序[运行期间]再确定如:实例化对象,方法调用,属性操作等.
 * 反射可以提高代码的灵活度,但是运行效率较低,开销较大,因此不能过度使用.
 */
public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        /*
            反射机制的第一步:获取要操作的类的类对象(Class的实例)
            Class类,该类的每一个实例用于表示JVM加载的一个类的所有信息.
            当JVM在加载一个类时就会实例化一个Class实例并用该对象表示加载的类的
            相关信息(类名,包信息,方法信息,构造器信息,属性信息等等).

            Class的每一个实例称为类对象,在JVM内部,每个被加载的类都有且只有一个
            Class的实例与之绑定.

            获取一个类的类对象:
            方式1:类名.class
                 Class cls = String.class;
                 Class cls = int.class;
                 注意:基本类型只能用该方式获取类对象

            方式2:Class.forName(String className)
                 Class cls = Class.forName("java.lang.String");
                 参数是加载的类的完全限定名:包名.类名

            方式3:ClassLoader获取
         */

        //获取String的类对象
//        Class cls = String.class;
//        Class cls = ArrayList.class;

        /*
            java.lang.String
            java.io.FileInputStream
            java.util.HashMap
            java.util.ArrayList
         */
//        Class cls = Class.forName("java.lang.String");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个类名");
        String cName = scanner.nextLine();
        Class cls = Class.forName(cName);




        //获取类名(当前类对象所表示的类的完全限定名)
        String className = cls.getName();
        System.out.println(className);
        //单独获取类名
        className = cls.getSimpleName();
        System.out.println(className);
        /*
            Package是常见的反射对象之一,该类的每一个实例与Class道理一样,只是用于
            表示的是一个包的信息.提供的诸多get方法都是获取与其表示的包相关信息
         */
        Package pack = cls.getPackage();
        String packName = pack.getName();//获取包名
        System.out.println(packName);
        /*
            Method[] getMethods()
            通过类对象获取其表示的类的所有[公开]方法,包含从超类继承的方法

            常见的反射对象之一:
            java.reflect.Method:方法对象,该类的每一个实例用于表示一个方法
         */
        Method[] methods = cls.getMethods();
        for (Method method : methods){
            //获取方法名
            String name = method.getName();
            //返回该方法的参数个数
            int count = method.getParameterCount();
            System.out.println("方法名:"+name+",共有"+count+"个参数");
        }


    }
}











